package com.pixelengine;
////////////////////////////////////////////////////////
//
//
// 这个接口是C++回调Java进程的
//update 2022-2-13 1020
//update 2022-3-19
//update 2022-4-3 0800
//update 2022-6-6 1027 add debug infos output for finding bugs in getDataCollection
//update 2022-7-3 add getNearestDatetime with return DatetimeDisplay Object.
//update 2022-7-8 update DatetimeDisplay
//2022-7-27
//2024/4/6 for OEE
//
/////////////////////////////////////////////////////////


import com.pixelengine.Task26Oee.FilenameReplacer;
import com.pixelengine.Task26Oee.ProductInfos;
import com.pixelengine.Task26Oee.TheConfig;

import java.io.*;
import java.nio.ByteBuffer;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.locks.ReentrantLock;


public class TileFilePixelEngineHelper {


    //get one tile data
    //bandindices is not used, just return all bands data.
    public TileData getTileData( long dt, String dsName,int[] bandindices,int z,int y,int x)
    {
        if(TheConfig.getInstance().debuginfo>0)
        {
            System.out.println("getTileData dsName: "+dsName);
            System.out.println("in java getTileData z,y,x,dt: "+z + "," + y+","+x+","+dt ) ;//2022-6-6
        }

        ProductInfos.ProductInfo pinfo = ProductInfos.getInstance().productDict.get(dsName);
        if(pinfo!=null) {
            if( pinfo.hTableName.equals("COG")) {
                String cogfilename = TheConfig.getInstance().cog_dir+dsName+"/"+String.valueOf(dt)+".tif" ;
                if(pinfo.filenameTemplate!=null &&  pinfo.filenameTemplate.isEmpty()==false ) {
                    String fileName1 = FilenameReplacer.replace(pinfo.filenameTemplate,String.valueOf(dt)) ;
                    cogfilename = TheConfig.getInstance().cog_dir+fileName1 ;
                }
                if( Files.exists(Paths.get(cogfilename)) ){
                    try{
                        PeTiler tiler = new PeTiler();
                        TileComputeResult res=null;
                        if(pinfo.resampleAlg==0)res=tiler.GetTileDataFromCog(
                                cogfilename,"EPSG:4326",256,256,z,y,x,pinfo.nodata);
                        else res=tiler.GetTileDataFromCog2(
                                cogfilename,"EPSG:4326",256,256,z,y,x,pinfo.nodata,
                                pinfo.resampleAlg,
                                TheConfig.getInstance().debuginfo
                                );
                        if( res==null) {
                            if(TheConfig.getInstance().debuginfo>0)
                            {
                                System.out.println("Debug tiler.GetTileDataFromCog|2 return null.");
                            }
                            return null ;
                        }
                        TileData tiledata = new TileData(1) ;// 1 means one datetime data.
                        tiledata.datetimeArray[0] = dt ;
                        tiledata.numds = 1;
                        tiledata.x = x ;
                        tiledata.y = y ;
                        tiledata.z = z ;
                        tiledata.width = pinfo.tileWid ;
                        tiledata.height = pinfo.tileHei ;
                        tiledata.nband = pinfo.nbands ;//
                        tiledata.dataType = pinfo.dataType ;
                        tiledata.tiledataArray[0] = res.binaryData ;
                        return tiledata;
                    }catch (Exception e) {
                        return null ;
                    }
                }
            }else{
                String tileFilename = TheConfig.getInstance().tile_file_dir
                        +dsName+"/"
                        +String.valueOf(dt) + "/"
                        +String.valueOf(z)+"/"
                        +String.valueOf(x)+"/"
                        +String.valueOf(y)+".raw" ;
                if( Files.exists(Paths.get(tileFilename)) ){
                    try{
                        byte[] tileByteData = Files.readAllBytes(Paths.get(tileFilename)) ;
                        TileData tiledata = new TileData(1) ;// 1 means one datetime data.
                        tiledata.datetimeArray[0] = dt ;
                        tiledata.numds = 1;
                        tiledata.x = x ;
                        tiledata.y = y ;
                        tiledata.z = z ;
                        tiledata.width = pinfo.tileWid ;
                        tiledata.height = pinfo.tileHei ;
                        tiledata.nband = pinfo.nbands ;//
                        tiledata.dataType = pinfo.dataType ;
                        tiledata.tiledataArray[0] = tileByteData ;
                        return tiledata;
                    }catch (Exception e) {
                        return null ;
                    }
                }
            }
        }
        return null;
    }

    // 拼接文件路径时，增加了{EXTRA}变量，主要用于支持起报时间
    public TileData getTileData2( long dt, String dsName, String extra,int[] bandindices,int z,int y,int x)
    {
        if(TheConfig.getInstance().debuginfo>0)
        {
            System.out.println("getTileData dsName: "+dsName);
            System.out.println("in java getTileData z,y,x,dt: "+z + "," + y+","+x+","+dt ) ;//2022-6-6
        }

        ProductInfos.ProductInfo pinfo = ProductInfos.getInstance().productDict.get(dsName);
        if(pinfo!=null) {
            if( pinfo.hTableName.equals("COG")) {
                String cogfilename = TheConfig.getInstance().cog_dir+dsName+"/"+String.valueOf(dt)+".tif" ;
                if(pinfo.filenameTemplate!=null &&  pinfo.filenameTemplate.isEmpty()==false ) {
                    String fileName1 = FilenameReplacer.replace2(pinfo.filenameTemplate,String.valueOf(dt),extra) ;
                    cogfilename = TheConfig.getInstance().cog_dir+fileName1 ;
                }
                if( Files.exists(Paths.get(cogfilename)) ){
                    try{
                        PeTiler tiler = new PeTiler();
                        TileComputeResult res=null;
                        if(pinfo.resampleAlg==0)res=tiler.GetTileDataFromCog(
                                cogfilename,"EPSG:4326",256,256,z,y,x,pinfo.nodata);
                        else res=tiler.GetTileDataFromCog2(
                                cogfilename,"EPSG:4326",256,256,z,y,x,pinfo.nodata,
                                pinfo.resampleAlg,
                                TheConfig.getInstance().debuginfo
                        );
                        if( res==null) {
                            if(TheConfig.getInstance().debuginfo>0)
                            {
                                System.out.println("Debug tiler.GetTileDataFromCog|2 return null.");
                            }
                            return null ;
                        }
                        TileData tiledata = new TileData(1) ;// 1 means one datetime data.
                        tiledata.datetimeArray[0] = dt ;
                        tiledata.numds = 1;
                        tiledata.x = x ;
                        tiledata.y = y ;
                        tiledata.z = z ;
                        tiledata.width = pinfo.tileWid ;
                        tiledata.height = pinfo.tileHei ;
                        tiledata.nband = pinfo.nbands ;//
                        tiledata.dataType = pinfo.dataType ;
                        tiledata.tiledataArray[0] = res.binaryData ;
                        return tiledata;
                    }catch (Exception e) {
                        return null ;
                    }
                }
            }else{
                String tileFilename = TheConfig.getInstance().tile_file_dir
                        +dsName+"/"
                        +String.valueOf(dt) + "/"
                        +String.valueOf(z)+"/"
                        +String.valueOf(x)+"/"
                        +String.valueOf(y)+".raw" ;
                if( Files.exists(Paths.get(tileFilename)) ){
                    try{
                        byte[] tileByteData = Files.readAllBytes(Paths.get(tileFilename)) ;
                        TileData tiledata = new TileData(1) ;// 1 means one datetime data.
                        tiledata.datetimeArray[0] = dt ;
                        tiledata.numds = 1;
                        tiledata.x = x ;
                        tiledata.y = y ;
                        tiledata.z = z ;
                        tiledata.width = pinfo.tileWid ;
                        tiledata.height = pinfo.tileHei ;
                        tiledata.nband = pinfo.nbands ;//
                        tiledata.dataType = pinfo.dataType ;
                        tiledata.tiledataArray[0] = tileByteData ;
                        return tiledata;
                    }catch (Exception e) {
                        return null ;
                    }
                }
            }
        }
        return null;
    }



    //get tile data array
    //deprecated 2022-4-3
    public TileData getTileDataArray(long fromdtInclude,long todtInclude ,
                                     String dsName, int[] bandindices ,
                                     int z,int y,int x,
                                     int filterMon,int filterDay,int filterHour,
                                     int filterMinu,int filterSec
                                     )
    {
        System.out.println("in java getTileDataArray zyx: "+z + "," + y+","+x ) ;
        return null ;
    }

    //2022-4-3
    public TileData getTileDataCollection( String dsName, long[] dtarr, int z,int y,int x)
    {
        System.out.println("in java getTileDataCollection dtarr.len " + dtarr.length + " z,y,x " + z + "," + y+","+x ) ;
        return null ;
    }

    //2022-4-10
    public synchronized byte[] getRoi3( String roiname) throws IOException {

        byte[] roidata = TheConfig.getInstance().getRoiData(roiname);
        return roidata ;
    }

}

